package com.sy.aspect;

import com.sy.annotation.PermissionAnnotation;
import com.sy.exception.BusinessException;
import com.sy.filter.RoleHolder;
import com.sy.utils.ReflectUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author Monkey-D-Gu
 * @version 1.0
 * @date 2020/9/11 0011 14:40
 * @usage 用面向切面的思想在所有方法执行前判断注解中的权限
 */
@Aspect
@Component
public class PowerEnsureAspect {

    /**
     * 切点
     */
    @Pointcut("execution(* com.sy.sevice.*.*(..))")
    public void method() {

    }

    /**
     * 环绕通知
     *
     * @param joinPoint
     * @return
     */
    @Around("method()")
    public Object permissionCheck(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕通知...");
        //获取方法的名称
        String methodName = joinPoint.getSignature().getName();
        //获取当前类
        Class<?> clazz = joinPoint.getTarget().getClass();
        //获取当前方法对象
        Method method = ReflectUtils.getMethod(clazz, methodName);
        //获取当前方法上的PermissionAnnotation注解
        PermissionAnnotation permissionAnnotation = method.getDeclaredAnnotation(PermissionAnnotation.class);
        Object[] args = joinPoint.getArgs();
        //判空,如果为空，代表方法不需要权限拦截
        if (null == permissionAnnotation) {
            //判断是否方法中有参数
            if (null == args || args.length == 0) {
                return joinPoint.proceed();
            } else {
                return joinPoint.proceed(args);
            }
        } else {
            //获取注解中的角色信息数组
            PermissionAnnotation.Role[] roles = permissionAnnotation.value();
            //获取当前线程中的角色信息
            PermissionAnnotation.Role curRole = RoleHolder.getCurRole();
            if (null == curRole) {
                throw new BusinessException("您未登录");
            } else {
                //是否包含
                if (Arrays.asList(roles).contains(curRole)) {
                    //判断是否方法中有参数
                    if (null == args || args.length == 0) {
                        return joinPoint.proceed();
                    } else {
                        return joinPoint.proceed(args);
                    }
                } else {
                    throw new BusinessException("您当前没有权限来操作");
                }
            }
        }
    }
}
